import os
import time
import requests
from fastapi import APIRouter, Header, HTTPException
from pydantic import BaseModel, Field
from typing import List, Optional

from models.m import (
    Novel,
    NovelCategory,
    NovelStatus,
    AuditStatus,
    User,
    UserRole,
)
from tool.jwt_utils import verify_token
from qiniu import Auth, put_data

writer_router = APIRouter()

QINIU_ACCESS_KEY = os.getenv("QINIU_ACCESS_KEY", "IPzQQFeLOA4fPDWzUTQQX7eJ4OcAfyzDyR3A3HN6")
QINIU_SECRET_KEY = os.getenv("QINIU_SECRET_KEY", "hi1t3IWhYxp5H-SI7sJnFLHR9x_oUt8mFeYtuz6z")
QINIU_BUCKET = os.getenv("QINIU_BUCKET", "653ef")
QINIU_DOMAIN = os.getenv("QINIU_DOMAIN", "http://t4y377zln.hb-bkt.clouddn.com")


@writer_router.get("/novels", summary="获取当前作者的全部作品（私有）", tags=["小说"])
async def get_my_novels_private(authorization: str | None = Header(None)):
    try:
        if not authorization or not authorization.lower().startswith("bearer "):
            raise HTTPException(status_code=401, detail="未授权：缺少Bearer Token")

        token = authorization.split(" ", 1)[1].strip()
        payload = verify_token(token)
        if not payload or not payload.get("user_id"):
            raise HTTPException(status_code=401, detail="无效或过期的Token")

        user_id = payload["user_id"]
        novels = await Novel.filter(user_id=user_id).order_by("-updated_at").prefetch_related("category")

        items = []
        for n in novels:
            items.append({
                "id": n.id,
                "title": n.title,
                "category_name": n.category.name if n.category_id else "",
                "status": int(n.status),
                "audit_status": int(n.audit_status),
                "word_count": n.word_count,
                "view_count": n.view_count,
                "collect_count": n.collect_count,
                "is_featured": n.is_featured,
                "updated_at": str(n.updated_at) if n.updated_at else None,
            })

        return {"code": 200, "message": "获取成功", "data": {"list": items, "total": len(items)}}

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取作者作品失败: {str(e)}")







# 创建作品
# 创建作品
class CreateNovelRequest(BaseModel):
    title: str = Field(..., description="小说标题", min_length=1, max_length=200)
    category_id: int = Field(..., description="分类ID")
    description: Optional[str] = Field(None, description="小说简介")
    cover_url: Optional[str] = Field(None, description="封面URL")
    tags: Optional[List[str]] = Field(default=None, description="标签数组")


class UploadCoverRequest(BaseModel):
    image_url: str = Field(..., description="需要上传到七牛云的图片URL")


@writer_router.post("/novels", summary="创建作品（私有）", tags=["小说"])
async def create_novel_private(
    payload: CreateNovelRequest,
    authorization: str | None = Header(None),
):
    if not authorization or not authorization.lower().startswith("bearer "):
        raise HTTPException(status_code=401, detail="未授权：缺少Bearer Token")

    token = authorization.split(" ", 1)[1].strip()
    payload_token = verify_token(token)
    if not payload_token or not payload_token.get("user_id"):
        raise HTTPException(status_code=401, detail="无效或过期的Token")

    user_id = payload_token["user_id"]
    user = await User.get_or_none(id=user_id)
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")

    if user.role not in (UserRole.AUTHOR, UserRole.ADMIN):
        raise HTTPException(status_code=403, detail="只有作者或管理员可以创建作品")

    category = await NovelCategory.get_or_none(id=payload.category_id)
    if not category:
        raise HTTPException(status_code=400, detail="分类不存在")

    title = payload.title.strip()
    if not title:
        raise HTTPException(status_code=400, detail="小说标题不能为空")

    existing = await Novel.filter(user_id=user_id, title=title).first()
    if existing:
        raise HTTPException(status_code=400, detail="该用户已经存在同名作品")

    novel = await Novel.create(
        user_id=user_id,
        title=title,
        author=user.nickname or user.phone or f"作者{user_id}",
        category=category,
        description=payload.description,
        cover_url=payload.cover_url,
        tags=payload.tags or [],
        status=NovelStatus.SERIALIZING,
        audit_status=AuditStatus.PENDING,
    )

    return {
        "code": 200,
        "message": "作品创建成功",
        "data": {
            "id": novel.id,
            "title": novel.title,
            "status": int(novel.status),
            "audit_status": int(novel.audit_status),
        },
    }


@writer_router.post("/upload-cover", summary="上传封面到七牛云", tags=["小说"])
async def upload_cover_to_qiniu(
    payload: UploadCoverRequest,
    authorization: str | None = Header(None),
):
    if not authorization or not authorization.lower().startswith("bearer "):
        raise HTTPException(status_code=401, detail="未授权：缺少Bearer Token")

    token = authorization.split(" ", 1)[1].strip()
    payload_token = verify_token(token)
    if not payload_token or not payload_token.get("user_id"):
        raise HTTPException(status_code=401, detail="无效或过期的Token")

    image_url = payload.image_url.strip()
    if not image_url.startswith("http"):
        raise HTTPException(status_code=400, detail="图片地址不合法")

    try:
        resp = requests.get(image_url, timeout=10)
        resp.raise_for_status()
        image_bytes = resp.content
        if len(image_bytes) == 0:
            raise ValueError("图片内容为空")
    except Exception as exc:
        raise HTTPException(status_code=502, detail=f"下载图片失败: {exc}")

    filename = f"novel_covers/{int(time.time())}_{os.path.basename(image_url.split('?')[0]) or 'cover.png'}"
    q = Auth(QINIU_ACCESS_KEY, QINIU_SECRET_KEY)
    upload_token = q.upload_token(QINIU_BUCKET, filename, 3600)

    try:
        ret, info = put_data(upload_token, filename, image_bytes)
        if info.status_code != 200:
            raise HTTPException(status_code=502, detail="上传七牛云失败")
    except Exception as exc:
        raise HTTPException(status_code=502, detail=f"上传七牛云失败: {exc}")

    qiniu_url = f"{QINIU_DOMAIN}/{filename}"

    return {
        "code": 200,
        "message": "上传成功",
        "data": {
            "url": qiniu_url,
            "key": filename,
        },
    }